package com.sx.netty.netty.demo01_GroupChat;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.EventExecutorGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Author ShuXin
 * @Description
 * @Date 2020/11/18 10:08
 */
public class GroupChatServerHandler extends SimpleChannelInboundHandler<String> {

    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

    //    创建连接时，执行一次
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
//        将该用户上线的消息推送给其他的所有在线的用户
        channelGroup.writeAndFlush(sdf.format(new Date()) + "\t[客户端]" + channel.remoteAddress().toString().substring(1)+ "已上线。");
//        将channel加入channelGroup中
        channelGroup.add(channel);
        System.out.println("channelGroup含有的channel的数量：" + channelGroup.size());
    }

    //    断开连接时，执行一次
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channelGroup.writeAndFlush(sdf.format(new Date()) + "\n[客户端]" + channel.remoteAddress().toString().substring(1) + "离线了。");
        System.out.println("channelGroup含有的channel的数量：" + channelGroup.size());
    }

    //    创建连接时执行一次，与handlerAdded()功能类似，但在该方法的执行之后再执行
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("【客户端】" + ctx.channel().remoteAddress().toString().substring(1) + "已上线");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("【客户端】" + ctx.channel().remoteAddress().toString().substring(1) + "离线");
    }

    //    channelActive0()方法中调用了channelActive()，对channelActive()的执行进行了判断：对传入的参数的类型进行了判断
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
//       获取当前channel
        Channel channel = channelHandlerContext.channel();
//        遍历channelGroup，会送消息
        channelGroup.forEach(ch -> {
            if (ch != channel)
                ch.writeAndFlush(channel.remoteAddress().toString().substring(1) + "说：" + s);
            else
                ch.writeAndFlush("自己发送消息：" + s);
        });
    }

//    当发生异常时，执行该方法
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//        关闭通道
        ctx.close();
    }
}
